package com.why.rpc.core.server.handler;


import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import com.why.rpc.core.common.enums.ErrorEnum;
import com.why.rpc.core.common.exception.RpcException;
import com.why.rpc.core.common.message.RpcRequest;
import com.why.rpc.core.common.message.RpcResponse;
import com.why.rpc.core.server.pool.ThreadPoolFactroy;
import com.why.simpleboot.core.core.ApplicationContext;
import com.why.simpleboot.core.core.factory.BeanFactory;

import java.util.concurrent.ExecutorService;

/**
 * @program: why-rpc-framework
 * @description:通道处理程序，完成对获取到的数据的处理
 * @author: @why
 * @create: 2021-03-16 10:03
 **/

public class NettyServerHandler extends SimpleChannelInboundHandler<RpcRequest> {
    private static ExecutorService poolService;
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NettyServerHandler.class);
    private BeanFactory beanFactory = ApplicationContext.getAnnotationApplicationContext().getBeanFactory();

    static {
        poolService = ThreadPoolFactroy.getExecutorService("netty-server-worker");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("通道被激活。。。");
        super.channelInactive(ctx);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequest msg) {
        if(msg.isFlag()){
            log.info("客户端心跳包{}",msg);
            return;
        }
        try {
            log.info("通道收到远程发送过来的请求:{}，开始进行请求处理", msg);


            //将当前任务交给线程池
            poolService.execute(() -> {
                log.info("去ioc获取服务。。。{}",Thread.currentThread().getName());
//                去ioc容器中获取对象
                Object service = beanFactory.getBeanByName(msg.getInterfaceName());
                log.info("将请求交给线程{}去处理请求。。。", Thread.currentThread().getName());
                Object result = RequestHandler.handler(service, msg);
                log.info("处理请求完成，获得的数据为:{}" , result);
                log.info("将数据写回开始。。。");
                ChannelFuture future = ctx.writeAndFlush(RpcResponse.isSuccess(result));
                future.addListener(ChannelFutureListener.CLOSE);
            });
            log.info( "劳动者继续工作。。。。。{}",Thread.currentThread().getName());
        } catch (Exception e) {
            log.info("nett-server-handler处理程序发生未知异常。。。", e);
            throw new RpcException(ErrorEnum.NOT_FOUND);

        } finally {
            ReferenceCountUtil.release(msg);
        }

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("服务端handler发生了异常。。。");
        super.exceptionCaught(ctx, cause);
    }


   /**
   * @Date   2021/7/12 11:40
   * @Param
   * @Return
   * @Exception  Exception
    * 覆盖了 handlerRemoved() 事件处理方法。
    * 每当从服务端收到客户端断开时
   *
   */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("client exit");
        super.handlerRemoved(ctx);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if( evt instanceof IdleStateEvent){
            IdleState state = ((IdleStateEvent) evt).state();
            if(state == IdleState.READER_IDLE){
                log.info("长时间未收到心跳包，断开连接……");
                ctx.close();
            }

        }else{
            super.userEventTriggered(ctx, evt);
        }

    }
}
